package org.gap.jseed.injection;

import java.lang.reflect.Method;

import org.gap.jseed.utils.Defense;

import javassist.*;
import javassist.bytecode.Descriptor;


/* package */ class CtMethodLocator {
	private final CtClass clazz;

	public CtMethodLocator(CtClass clazz) {
		this.clazz = clazz;
	}

	public CtMethod find(Method method) {
		Defense.argumentNotNull(method, "Method cannot be null");
		
		CtClass[] paramTypes = getCtParameters(method);
		CtClass returnType = getCtReturnType(method);
		String descriptor = Descriptor.ofMethod(returnType, paramTypes);
		
		try {
			return clazz.getMethod(method.getName(), descriptor);
		} catch (NotFoundException e) {
			throw new IllegalStateException(e.getMessage());
		}
	}
	
	private CtClass[] getCtParameters(Method method) {
		CtClass[] paramTypes = new CtClass[method.getParameterTypes().length];
		for (int i = 0; i < paramTypes.length; i++) {
			Class<?> parameter = method.getParameterTypes()[i];
			paramTypes[i] = CtClassLocator.getCtClass(parameter);
		}
		return paramTypes;
	}
	
	private CtClass getCtReturnType(Method method){
		CtClass returnType = null;
		if (method.getReturnType().equals(Void.class)) {
			returnType = CtClass.voidType;
		} else {
			returnType = CtClassLocator.getCtClass(method.getReturnType());
		}
		return returnType;
	}
}
